home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Sound / MIDI / MIDI Utilities / CMU Midi Toolkit / Source / midiparse.c < prev    next >
Text File  |  1987-01-27  |  12KB  |  387 lines

  1. /* midiparse.c
  2.  *
  3.  * midiparse parses incoming midi data.  the data arrives one byte at a
  4.  * time via calls to process_byte from the input interrupt handler.
  5.  * normal (NOT system exclusive) midi messages are placed in the shared
  6.  * buffer "buff" (defined in macmidi.c) while system exclusive messages
  7.  * are placed in "xbuff", if it is not NULL. (xbuff is supplied by the
  8.  * client, if he is interested in system exclusive messages, through a
  9.  * call to midi_buffer.)  if the shared variable "ctrlFilter" is true,
  10.  * then continuous controller data and key/channel after-touch are
  11.  * filtered out of the midi stream.  "ctrlFilter" may be set by calling
  12.  * midi_cont in macmidi.c.
  13.  */
  14.  
  15. /*****************************************************************************
  16. *        Change Log
  17. *    Date    |    Change
  18. *-----------+-----------------------------------------------------------------
  19. * 16-Jan-87 | JMaloney: Converted to Lightspeed C
  20. *****************************************************************************/
  21.  
  22. #include <StdIO.h>
  23. #include "cext.h"
  24. #include "midibuff.h"
  25. #include "midiparse.h"
  26.  
  27. /****************************************************************************
  28. *
  29. *    constants and types
  30. *
  31. ****************************************************************************/
  32.  
  33. /* some constants for parsing MIDI status bytes */
  34. #define STATUS_BIT 0x80
  35. #define HIGH_NIBBLE 0xF0
  36. #define LOW_NIBBLE 0x0F
  37. #define SYSTEM_MESSAGE 0xF0
  38. #define CHANNEL_CMD 0x70
  39.  
  40. /* some MIDI status bytes */
  41. #define END_BLOCK_STATUS 0xF7
  42. #define NOTE_OFF_STATUS 0x80
  43. #define PITCH_BEND_STATUS 0xE0
  44.  
  45. enum receive_state {
  46.     idle, system_exclusive, interesting, boring};
  47.  
  48. /****************************************************************************
  49. *
  50. *    variables shared with other modules
  51. *
  52. ****************************************************************************/
  53.  
  54. /* imported: midi input buffer */
  55. extern byte buff[BUFF_SIZE];    /* data buffer */
  56. extern int bufftail;            /* buffer tail (insertion point) */
  57. extern int buffhead;            /* buffer head */
  58.  
  59. /* imported: user supplied system exclusive buffer */
  60. extern byte *xbuff;        /* address of the user-supplied buffer (or NULL) */
  61. extern int xbuffmask;    /* mask for circular buffer address calculation */
  62. extern int xbufftail;    /* buffer tail (insertion point) */
  63. extern int xbuffhead;    /* buffer head */
  64.  
  65. /* imported: */
  66. extern boolean ctrlFilter;
  67.  
  68. /* exported: errors are signalled by setting bits in midi_error */
  69. public int midi_error = 0;
  70.  
  71. /****************************************************************************
  72. *
  73. *    variables private to this module (parser's "state")
  74. *
  75. ****************************************************************************/
  76.  
  77. private int last_status_byte = 0;    /* status byte of the current
  78.                                      * or most recent command; keeps midi
  79.                                      * "running status" */
  80.  
  81. private int bytes_wanted = 0;    /* bytes of data for current command */
  82. private byte data[2];            /* buffer in which to accumulate data bytes */
  83. private int rcv_count = 0;        /* number of bytes in "data" */
  84.  
  85. private enum receive_state state, saved_state = idle;
  86.     /* state is the current state
  87.      * saved_state is the state pushed when we are interrupted by
  88.      *   a higher priority (i.e. system exclusive) message */
  89.  
  90.  
  91. /****************************************************************************
  92. *
  93. *    routines private to this module
  94. *
  95. ****************************************************************************/
  96.  
  97. void    block_end(void);
  98. void    data_byte(int);
  99. void    put_xbyte(int);
  100. void    reset(void);
  101. void    set_error(int);
  102. void    state_error(void);
  103. void    undefined(void);
  104. void    unexpected(void);
  105. void    use_running_status(int);
  106.  
  107. /****************************************************************************
  108. *                    block_end
  109. * Effect:
  110. *    a block end status byte terminates a system exclusive message
  111. ****************************************************************************/
  112.  
  113. private void block_end()
  114. {
  115.     /* put eob in system exclusive buffer */
  116.     put_xbyte(END_BLOCK_STATUS);
  117.     state = saved_state;    /* restore state to what it was when we were
  118.     saved_state = idle;          * so rudely interrupted */
  119. }
  120.  
  121. /****************************************************************************
  122. *                    data_byte
  123. * Effect:
  124. *    accept a data byte.
  125. *    the behavior of this procedure depends on the state of the parser.
  126. *    if we are in the midst of receiving a sytem exclusive message:
  127. *        put the data byte in the system exclusive buffer
  128. *    if this byte completes a midi command:
  129. *        if it is an "interesting" command,
  130. *            put the entire command into the normal midi buffer
  131. *        in any event, reset the parser to the idle state
  132. *    if we are in the idle state:
  133. *        use "running status" to figure what the command byte for this
  134. *        data byte should have been and set the parser state accordingly
  135. ****************************************************************************/
  136.  
  137. private void data_byte(c)
  138.     register int c;
  139. {
  140.     if (state == system_exclusive) {
  141.         /* midi exclusive data byte */
  142.         if (xbuff != NULL) put_xbyte(c);
  143.     } else if (bytes_wanted > 0) {
  144.         /* data byte for a midi command */
  145.         data[rcv_count++] = (byte) c;
  146.         if (rcv_count == bytes_wanted) {    /* got a complete command */
  147.             if (state == interesting) {        /* interesting, so save it */
  148.                 register byte *dataPtr;
  149.  
  150.                 dataPtr = buff + bufftail;
  151.                 *dataPtr++ = last_status_byte;
  152.                 *dataPtr++ = data[0];
  153.                 *dataPtr++ = data[1];
  154.                 *dataPtr++ = 0;    /* there are at most two data bytes */
  155.                 bufftail = (bufftail + 4) & BUFF_MASK;
  156.                 if (bufftail == buffhead) {
  157.                     /* filled buffer faster than client emptied it */
  158.                     set_error(DATA_OVERRUN);
  159.                 }
  160.             }
  161.             reset();
  162.         }
  163.     } else {
  164.         /* must be in the idle state; this is a data byte with an implied
  165.          * status byte equal to that of the last status byte received */
  166.         use_running_status(c);
  167.     }
  168. }
  169.  
  170. /****************************************************************************
  171. *                    process_byte
  172. * Effect:
  173. *    the heart of the parser.
  174. *    see the midi 1.0 specification for clarification.
  175. ****************************************************************************/
  176.  
  177. public void process_byte(c)
  178.     register int c;
  179. {
  180.     if (!(c & STATUS_BIT)) {
  181.         /* data byte for a command */
  182.         data_byte(c);
  183.     } else {
  184.         /* midi status byte -- the start of a command */
  185.         if ((c & HIGH_NIBBLE) == SYSTEM_MESSAGE) {
  186.             /* a system message */
  187.             switch (c & LOW_NIBBLE) {
  188.                 /* case 0 is a system exclusive message */
  189.                 case  0:
  190.                     if (saved_state != idle) state_error();
  191.                         /* a system exclusive message cannot interrupt
  192.                          * another system exclusive message! */
  193.                     saved_state = state;
  194.                     state = system_exclusive;
  195.                     if (xbuff != NULL) put_xbyte(c);
  196.                     break;
  197.  
  198.                 /* cases 1 through 7 are system common messages */
  199.              /* case  1: *** undefined -- see default case ***  */
  200.                 case  2: /* measure select (msbits, lsbits) */
  201.                     if (state != idle) state_error();
  202.                     last_status_byte = c;
  203.                     state = boring;
  204.                     bytes_wanted = 2;
  205.                     unexpected();
  206.                     break;
  207.                 case  3: /* song select (song_number) */
  208.                     if (state != idle) state_error();
  209.                     last_status_byte = c;
  210.                     state = boring;
  211.                     bytes_wanted = 1;
  212.                     unexpected();
  213.                     break;
  214.              /* case  4: *** undefined -- see default case ***  */
  215.              /* case  5: *** undefined -- see default case ***  */
  216.                 case  6: /* tune request */
  217.                     unexpected();
  218.                     break;
  219.                 case  7: /* end of block */
  220.                     block_end();
  221.                     break;
  222.  
  223.                 /* cases 8 through 15 are system real-time messages */
  224.                 /* they have no data bytes and are not of interest to us */
  225.                 case  8: /* timing clock - during play */
  226.                 case  9: /* timing clock with measure end */
  227.                 case 10: /* start - from first measure */
  228.                 case 11: /* start - continue */
  229.                 case 12: /* timing clock - during stop */
  230.                     unexpected();
  231.                     break;
  232.              /* case 13: *** undefined -- see default case ***  */
  233.                 case 14: /* running status */
  234.                     /* expected but boring -- throw it away */;
  235.                     break;
  236.                 case 15: /* system reset */
  237.                     unexpected();
  238.                     break;
  239.                 default:
  240.                     undefined();
  241.                     break;
  242.             }
  243.         } else {
  244.             /* channel message */
  245.             switch ((c & CHANNEL_CMD) >> 4) {
  246.                 case 0: /* note off */
  247.                     if (state != idle) state_error();
  248.                     last_status_byte = c;
  249.                     state = interesting;
  250.                     bytes_wanted = 2;
  251.                     break;
  252.                 case 1: /* note on */
  253.                     if (state != idle) state_error();
  254.                     last_status_byte = c;
  255.                     state = interesting;
  256.                     bytes_wanted = 2;
  257.                     break;
  258.                 case 2: /* key pressure */
  259.                     if (state != idle) state_error();
  260.                     last_status_byte = c;
  261.                     state = (ctrlFilter) ? boring : interesting;
  262.                     bytes_wanted = 2;
  263.                     break;
  264.                 case 3: /* control change */
  265.                     if (state != idle) state_error();
  266.                     last_status_byte = c;
  267.                     state = (ctrlFilter) ? boring : interesting;
  268.                     bytes_wanted = 2;
  269.                     break;
  270.                 case 4: /* program change */
  271.                     if (state != idle) state_error();
  272.                     last_status_byte = c;
  273.                     state = interesting;
  274.                     bytes_wanted = 1;
  275.                     break;
  276.                 case 5: /* channel pressure */
  277.                     if (state != idle) state_error();
  278.                     last_status_byte = c;
  279.                     state = (ctrlFilter) ? boring : interesting;
  280.                     bytes_wanted = 1;
  281.                     break;
  282.                 case 6: /* pitch bend */
  283.                     if (state != idle) state_error();
  284.                     last_status_byte = c;
  285.                     state = (ctrlFilter) ? boring : interesting;
  286.                     bytes_wanted = 2;
  287.                     break;
  288.                 case 7: /* system message, handled above */
  289.                 default:
  290.                     undefined();
  291.                     break;
  292.             }
  293.         }
  294.     }
  295. }
  296.  
  297. /****************************************************************************
  298. *                    put_xbyte
  299. * Effect:
  300. *    puts a midi-exclusive message byte into the client supplied buffer, if
  301. *    there is one.  notices overrun errors.
  302. ****************************************************************************/
  303.  
  304. private void put_xbyte(c)
  305.     register int c;
  306. {
  307.     if (xbuff != NULL) {
  308.         /* if the client has supplied a buffer, */
  309.         /*   save system exclusive data in it */
  310.         xbuff[xbufftail++] = (byte) c;
  311.         xbufftail &= xbuffmask;
  312.         if (xbufftail == xbuffhead) {
  313.             /* filled buffer faster than client emptied it */
  314.             set_error(EXCLUSIVE_DATA_OVERRUN);
  315.         }
  316.     }
  317. }
  318.  
  319. /****************************************************************************
  320. *                    reset
  321. * Effect:
  322. *    resets the parser's state after a complete midi command is received or
  323. *    after a state error occurs
  324. ****************************************************************************/
  325.  
  326. private void reset()
  327. {
  328.     state = idle;
  329.     saved_state = idle;
  330.     bytes_wanted = 0;
  331.     rcv_count = 0;
  332. }
  333.  
  334. /****************************************************************************
  335. *                    error handling
  336. * Effect:
  337. *    various error conditions are flagged by setting bits in
  338. *    the global midi_error.  it is up to the client to clear this word
  339. *    when necessary.
  340. ****************************************************************************/
  341.  
  342. private void set_error(bit)
  343.     int bit;
  344. {
  345.     midi_error |= bit;
  346. }
  347.  
  348. private void state_error()
  349. {
  350.     midi_error |= STATE_ERR;
  351.     reset();
  352. }
  353.  
  354. private void undefined()
  355. {
  356.     midi_error |= UNDEFINED_OP;
  357. }
  358.  
  359. private void unexpected()
  360. {
  361.     midi_error |= UNEXPECTED_OP;
  362. }
  363.  
  364. /****************************************************************************
  365. *                    use_running_status
  366. * Effect:
  367. *    called when a data byte arrives out of the blue, meaning that
  368. *    we should use the midi "running status" feature -- the command
  369. *    byte is implied to be the same as the last command byte received
  370. * Implementation:
  371. *    recursively calles process_byte to establish the right context
  372. ****************************************************************************/
  373.  
  374. private void use_running_status(data_byte)
  375.     int data_byte;
  376. {
  377.     /* Note: only channel messages may use running status */
  378.     if ((state == idle) &&
  379.         (((last_status_byte >= NOTE_OFF_STATUS) &&
  380.           (last_status_byte <= PITCH_BEND_STATUS)))) {
  381.              process_byte(last_status_byte);    /* recursive call */
  382.             process_byte(data_byte);        /* recursive call */
  383.     } else {
  384.         set_error(UNWANTED_DATA);
  385.     }
  386. }
  387.